<template>
  <!--
  @name: HyForm
  @data: 2024/4/12 14:58
-->
  <div id="hy_form">
    <el-form
      ref="ruleFormRef"
      :model="submitForm.model"
      :rules="submitForm.rules"
      :label-width="formJson.labelWidth?formJson.labelWidth:'100'"
      class="demo-ruleForm"
      :size="formJson.size?formJson.size:'default'"
      :inline="formJson.inline?formJson.inline:true"
      :require-asterisk-position="formJson.requireAsteriskPosition?formJson.requireAsteriskPosition:'left'"
      :label-position="formJson.labelPosition?formJson.labelPosition:'left'"
      :show-message="formJson.showMessage?formJson.showMessage:true"
      :inline-message="formJson.inlineMessage?formJson.inlineMessage:false"
      :scroll-to-error="formJson.scrollToError?formJson.scrollToError:false"
    >
      <!--   这里我们嵌套一个template,用于循环   -->
      <template v-for="item in formJson.formModelList"
      >
        <el-form-item
          :size="item.size as any"
          :label="item.label"
          :prop="item.field as string"
          :label-width="item.labelWidth?item.labelWidth:'100'"
        >
          <HyElInput
            v-if="item.inputType==='input'"
            :style="{width:`${formJson.itemWidth}px`}"
            :form="submitForm.model"
            :field="item.field"
            :url="item.url"
            :method="item.method"
            :params="item.params"
            :data="item.data"
            :disabled="item.isDisabled"
            :size="item.size"
            :id="item.id"
            :clearable="item.isClearable"
            :is-readonly="item.isReadonly!==undefined?item.isReadonly:formJson.isReadonly?formJson.isReadonly:false"
            @change="item.onChange"
            @focus="item.onFocus"
            @blur="item.onBlur"
            @click="item.click"
            :request-callback="item.requestCallback"
            :response-callback="item.responseCallback"
            :show-password="item.showPassword"
            :show-word-limit="item.showWordLimit"
            :suffix-icon="item.suffixIcon"
            :autofocus="item.autofocus"
          />

          <HyElDate
            v-if="item.inputType==='date'"
            :style="{width:`${formJson.itemWidth}px`}"
            :field="item.field"
            :type="item.type"
            :is-readonly="item.isReadonly!==undefined?item.isReadonly:formJson.isReadonly?formJson.isReadonly:false"
            :form="submitForm.model"
            :placeholder="item.placeholder"
            :time-format="item.timeFormat"
            :value-format="item.valueFormat"
            :range-separator="item.rangeSeparator as any"
            :start-date-field="item.startDateField as string"
            :end-date-field="item.endDateField as string"
            :id="item.id"
            :name="item.name"
            :change="item.onChange"
          />

          <HyElSelect
            v-if="item.inputType==='select'"
            :option-list="item.optionList"
            :form="submitForm.model"
            :field="item.field"
            :size="item.size"
            :option-key-field="item.optionKeyField"
            :option-label-field="item.optionLabelField"
            :option-value-field="item.optionValueField"
            :is-multiple="item.isMultiple"
            :multiple-limit="item.multipleLimit"
            :is-filterable="item.isFilterable"
            :loading-text="item.loadingText"
            :autocomplete="item.autocomplete"
            :value-key="item.valueKey"
            :is-collapse-tags="item.isCollapseTags"
            :collapse-tags-tooltip="item.collapseTagsTooltip"
            :filter-method="item.filterMethod"
            :visible-change="item.visibleChange"
            :placeholder="item.placeholder"
            :input-style="item.inputStyle"
            :url="item.url"
            :method="item.method"
            :response-callback="item.responseCallback"
            :request-callback="item.requestCallback"
            :data="item.data"
            :params="item.params"
          />

          <HyElUpload
            v-if="item.inputType==='upload'"
            input-type="upload"
            :name="item.name"
            :field="item.field"
            :form="submitForm.model"
            :url="item.url"
            :method="item.method"
            :params="item.params"
            :data="item.data"
            :input-style="item.inputStyle"
            :size="item.size"
            :id="item.id"
            :upload-field="item.uploadField"
            :multiple="item.multiple"
            :with-credentials="item.withCredentials"
            :show-file-list="item.showFileList"
            :drag="item.drag"
            :on-preview="item.onPreview"
            :on-remove="item.onRemove"
            :on-success="item.onSuccess"
            :on-error="item.onError"
            :on-progress="item.onProgress"
            :on-change="item.onChange as any"
            :on-exceed="item.onExceed"
            :before-upload="item.beforeUpload"
            :before-remove="item.beforeRemove"
            :file-list="item.fileList"
            :http-request="item.httpRequest"
            :limit="item.limit"
            :customComponent="item.customComponent"
            :prompt-information="item.promptInformation"
            :splicing-symbol="item.splicingSymbol"
            :is-download-file="item.isDownloadFile"
            :file-url-name-field="item.fileUrlNameField"
          />

          <!--    自定义组件      -->
          <HyCustomComponent
            v-if="item.inputType==='custom'"
            :component="item.component"
            :is-keep-alive="item.isKeepAlive"
            :value="item.value"
            :form="submitForm.model"
            :field="item.field"
          />

          <!--     树形选择器     -->
          <HyElTree
            v-if="item.inputType==='tree'"
            :form="submitForm.model"
            :data="item.data"
            :label-field="item.labelField"
            :value-field="item.valueField"
            :children-field="item.childrenField"
          />

        </el-form-item>

      </template>
      <el-form-item style="display: block;width: max-content; margin: 20px auto;">
        <el-button :size="formJson.size as any" type="primary" @click="submitFormFun(ruleFormRef)">{{formJson.submitBtnTitle?formJson.submitBtnTitle:"提交"}}</el-button>
        <el-button :size="formJson.size as any" @click="resetBtn(ruleFormRef)">{{formJson.cancelBtnTitle?formJson.cancelBtnTitle:"清空"}}</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>
<script setup lang="ts">
import HyFormInterface from "@/interface/HyFormInterface";
import {reactive, ref} from "vue";
import {ElForm, FormInstance} from "element-plus";
// @ts-ignore
import HyElInput from "@/components/HyFormItem/HyElInput.vue";
import type {UserListPageVO} from "@/api/test";
import type {Form} from "@/type";
// @ts-ignore
import HyElDate from "@/components/HyFormItem/HyElDate.vue";
// @ts-ignore
import HyElSelect from "@/components/HyFormItem/HyElSelect.vue";
import projectRequest from "@/api/index";
// @ts-ignore
import HyElUpload from "@/components/HyFormItem/HyElUpload.vue";
// @ts-ignore
import Test from "@/components/Test.vue";
// @ts-ignore
import HyCustomComponent from "@/components/HyFormItem/HyCustomComponent.vue";
// @ts-ignore
import HyElTree from "@/components/HyFormItem/HyElTree.vue";

interface HyFromInterface<T> {
  /**
   * @description 按钮是否在表格
   */
  isBtnInTheTable?: boolean,
  inLine?: boolean,
  formList?: T
}

//定义表单对象
interface UserInsertVO {
  phone: string,
  password: string,
}

const formJson=defineProps<HyFormInterface>();
/**
 * formItemJson中的数据
 * 将需要在form中表单使用的字段提取出来
 */
const submitForm = reactive({
  //用于参数提交的
  model: {} as UserInsertVO,
  //用于规则校验的
  rules: {},
});
/** 表单组件的ref */
const ruleFormRef = ref<FormInstance>();
/**
 * 表单对象生成
 * 由于我们交字段值分散了,所以需要遍历数组
 * 取出 键值对 和 校验规则
 *
 * */
function getFormItemJson() {
  //@ts-ignore
  console.log(132, process.env.NODE_ENV);
  const model: any = {};
  const rules: any = {};
  if (formJson.formModelList){
    formJson.formModelList.forEach((value: any) => {
      if (value.field) {
        if (value.value) {
          model[value.field] = value.value;
        } else {
          model[value.field] = undefined;
        }
      }
      if (value.rule) {
        rules[value.field ? value.field : ""] = value.rule;
      }
      submitForm.model = model;
      submitForm.rules = rules;
    });
  }
}

getFormItemJson();


/**
 * @description 提交表单事件
 * @param formEl
 */
const submitFormFun = async (formEl: FormInstance | undefined)=>{
  if (!formEl) return;
  await formEl.validate((isValid, invalidFields)=>{
    //校验成功
    if (isValid){
      //如果回调函数存在
      if (formJson.requestCallback){
        //执行submitBtnCallBackFun回调方法,并传入参数
          formJson.requestCallback(submitForm.model,formEl);
      }else {
        //如果回调函数不存在
        /** 整理data数据 */
        let data=submitForm.model;
        if (formJson.data){
          data={...data,...formJson.data};
        }
        /** 整理query数据 */
        let url=formJson.url;
        if (formJson.query){
          url+="/"+formJson.query.join("/");
        }
        console.log(201, url);
        projectRequest.request({
          method:formJson.method,
          url,
          data,
          params:formJson.params?formJson.params:undefined,
        }).then((result)=>{
          console.log(result);
          if (formJson.responseCallback){
            formJson.responseCallback(result);
          }
        },(error)=>{
          console.error(error);
        });
      }
    }else {
      //打印缺少的必填字段
      //@ts-ignore
      if (process.env.NODE_ENV==='development'){
        /** 全局展开打印 */
        console.error(JSON.parse(JSON.stringify(invalidFields)));
      }
      return false;
    }
  })
}


/**
 * @description 重置表单事件
 */
const resetBtn = async (formEl: FormInstance | undefined)=>{
  if (formJson.cancelBtnCallBackFun){
    formJson.cancelBtnCallBackFun(submitForm.model,formEl as FormInstance);
  }else{
    if (!formEl) return;
    /** 这里我们先用resetFields这个方法,后期肯定还要改 */
    formEl.resetFields();
  }
}

</script>
<style scoped>

</style>
